package com.kobe.tools.hystrix;

import com.netflix.hystrix.*;

/**
 * @author ：caopengfei
 * @date ：2020/12/2
 */
public class HttpClientHystrixCommand  extends HystrixCommand<String> {

    private HttpEntity httpEntity;

    private String fwid;

    private int  sleepTime;

    public HttpClientHystrixCommand(HttpEntity httpEntity,String fwid,int sleepTime) {
        super(HttpClientHystrixCommand.setter(fwid,fwid,fwid));
        this.sleepTime = sleepTime;
        this.fwid = fwid;
    }

    public HttpClientHystrixCommand(HystrixCommandGroupKey group, HttpEntity httpEntity, String fwid) {
        super(group);
        this.httpEntity = httpEntity;
        this.fwid = fwid;
    }

    @Override
    protected String run() throws Exception {
        //发送消息
        return HttpClient.send(sleepTime);
    }



    private static Setter setter(String groupId,String commandId,String threadKey) {

        // 服务分组
        HystrixCommandGroupKey groupKey = HystrixCommandGroupKey.Factory.asKey(groupId);
        // 服务标识
        HystrixCommandKey commandKey = HystrixCommandKey.Factory.asKey(commandId);
        // 线程池名称
        HystrixThreadPoolKey threadPoolKey = HystrixThreadPoolKey.Factory.asKey(threadKey);
        // #####################################################
        // 线程池配置 线程池大小为10,线程存活时间15秒 队列等待的阈值为100,超过100执行拒绝策略
        HystrixThreadPoolProperties.Setter threadPoolProperties = HystrixThreadPoolProperties.Setter().withCoreSize(100)
                .withKeepAliveTimeMinutes(15).withQueueSizeRejectionThreshold(10);
        // ########################################################
        // 命令属性配置Hystrix 开启超时
        HystrixCommandProperties.Setter commandProperties = HystrixCommandProperties.Setter()
                // 采用线程池方式实现服务隔离
                .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD)
                // 禁止
                .withExecutionTimeoutEnabled(true)
                //统计10s内数据失败率
                .withMetricsRollingStatisticalWindowInMilliseconds(2000)
                //每一秒进行一次健康检查
                .withMetricsHealthSnapshotIntervalInMilliseconds(500)
                //超时时间设置为5s
                .withExecutionTimeoutInMilliseconds(200)
                //开启服务降级
                .withFallbackEnabled(true)
                //启用断路器
                .withCircuitBreakerEnabled(true)
                //窗口时间内只要超过5个请求，并且失败率超过阈值就会进行熔断
                .withCircuitBreakerRequestVolumeThreshold(20)
                // 启动断路器多长时间就放行一个请求，来检测系统是否正常   设置10分钟
                .withCircuitBreakerSleepWindowInMilliseconds(30000)
                // 断路器错误百分比阈值 失败率超过80% 开启断路器
                .withCircuitBreakerErrorThresholdPercentage(100);
        return Setter.withGroupKey(groupKey).andCommandKey(commandKey).andThreadPoolKey(threadPoolKey)
                .andThreadPoolPropertiesDefaults(threadPoolProperties).andCommandPropertiesDefaults(commandProperties);

    }

    @Override
    protected String getFallback() {
        return "服务降级了啊";
    }
}
